package com.lhy.noed;

import com.alibaba.fastjson.JSONObject;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.util.*;

/**
 * @description: 对用户暴露的接口方法,用户执行常用的sql操作
 * @author: 李汇远
 */
public class GzExecute {

    JdbcTemplate jdbcTemplate;
    DbInfo dbInfo;
    SqlBuilder sqlBuilder;

    public GzExecute(JdbcTemplate jdbcTemplate){
        this.jdbcTemplate = jdbcTemplate;
        this.dbInfo = new DbInfo(jdbcTemplate);
        this.sqlBuilder = new SqlBuilder(dbInfo);
    }

    protected DbInfo getDbInfo(){
        return dbInfo;
    }

    // 添加新记录
    public Integer add(String tableName, JSONObject data){
        String sql =sqlBuilder.getInsertSql(tableName, data);
        Integer res = jdbcTemplate.update(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    // 删除记录
    public Integer remove(String tableName, String colName, String colData){
        String sql = sqlBuilder.getDeleteSql(tableName, colName, colData);
        Integer res = jdbcTemplate.update(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    /**
     * 删除字段为空值的部分
     * @param tableName
     * @param colName
     * @return
     */
    public Integer removeNull(String tableName,String colName){
        String sql = sqlBuilder.getDeleteSql(tableName, colName);
        Integer res = jdbcTemplate.update(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    /**
     *
     * @param tableName
     * @return
     */
    public List<Map<String, Object>> get(String tableName){
        String sql = sqlBuilder.getSelectSql(tableName);
        List<Map<String, Object>> res = jdbcTemplate.queryForList(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    public List<Map<String, Object>> get(String tableName, String where){
        String sql = sqlBuilder.getSelectSql(tableName, where);
        List<Map<String, Object>> res = jdbcTemplate.queryForList(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    public List<Map<String, Object>> get(String tableName, JSONObject params){
        String sql = sqlBuilder.getSelectSql(tableName, params);
        List<Map<String, Object>> res = jdbcTemplate.queryForList(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    public List<Map<String, Object>> get(String tableName, String colName, String colData){
        String sql = sqlBuilder.getSelectSql(tableName, colName, colData);
        List<Map<String, Object>> res = jdbcTemplate.queryForList(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    /**
     * 更新记录
     * @param tableName
     * @param content
     * @param where
     * @return
     */
    public Integer update(String tableName, String content, String where){
        String sql = sqlBuilder.getUpdateSql(tableName, content, where);
        Integer res = jdbcTemplate.update(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    public Integer update(String tableName, JSONObject params, String where){
        String sql = sqlBuilder.getUpdateSql(tableName, params, where);
        Integer res = jdbcTemplate.update(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    public Integer update(String tableName, String colName, String colData, String where){
        String sql = sqlBuilder.getUpdateSql(tableName, colName, colData,  where);
        Integer res = jdbcTemplate.update(sql);
        System.out.println("[GzExecute] SQL:"+sql);
        System.out.println("[GzExecute] Result:"+res);
        return res;
    }

    /**
     * 生成包含数据库表名称的常量类
     */
    public void generateTbNameConstClass() throws IOException {
        writeToClassFile("TB", getTbNameConstClassContent());
    }

    /**
     * 生成包含数据库表字段的常量类
     * @throws IOException
     */
    public void generateColNameConstClass() throws IOException {
        writeToClassFile("COL", getColNameConstClassContent());
    }

    /**
     * 获取数据库表的字段信息常量类内容
     * @return
     */
    private String getColNameConstClassContent(){
        String template = "\n// @author lhy \npublic class COL {\n%s\n\n}";
        String varTemplate = "\n\tpublic static final String %s$%s = \"%s\";";
        StringBuilder content = new StringBuilder();
        for (Map.Entry<String, List<String>> col: dbInfo.getColNames().entrySet()){
            content.append("\n\t// tableName:").append(col.getKey());
            for (String colName: col.getValue()){
                content.append(String.format(varTemplate, col.getKey().toUpperCase(), colName.toUpperCase(), colName));
            }
        }
        return String.format(template, content);
    }

    /**
     * 获取表名常量类的内容
     * @return
     */
    private String getTbNameConstClassContent(){
        String template = "\n// @author lhy \npublic class TB {\n%s\n\n}";
        String varTemplate = "\n\tpublic static final String %s = \"%s\";";
        StringBuilder content = new StringBuilder();
        for (String tbName: dbInfo.getTableNames()){
            content.append(String.format(varTemplate, tbName.toUpperCase(), tbName));
        }
        return String.format(template, content);
    }

    /**
     * 生成指定java文件
     * @param className
     * @param content
     * @return
     * @throws IOException
     */
    private void writeToClassFile(String className, String content) throws IOException {
        File file = new File(getProjectPath() + className + ".java");
        if (file.exists())
            throw new FileAlreadyExistsException("文件已存在: " + file.getPath());
        if (! file.createNewFile())
            throw new IOException("创建文件失败:"+file.getPath());
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
        bufferedWriter.write(content);
        bufferedWriter.flush();
        bufferedWriter.close();
    }

    /**
     * 获取项目路径
     * @return
     */
    private String getProjectPath(){
        String path = Objects.class.getResource("/").getPath();
        return path.substring(0, path.lastIndexOf("/target/")) + "/src/main/java/";
    }

    public JSONObject getEntity(String tbName){
        return dbInfo.getEntity(tbName);
    }

}
